{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import AutoTokenizer\n",
    "\n",
    "# 初始化tokenizer\n",
    "tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen2.5-0.5B-Instruct')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<|im_start|>system\n",
      "You are Qwen, created by Alibaba Cloud. You are a helpful assistant.\n",
      "\n",
      "# Tools\n",
      "\n",
      "You may call one or more functions to assist with the user query.\n",
      "\n",
      "You are provided with function signatures within <tools></tools> XML tags:\n",
      "<tools>\n",
      "{\"type\": \"function\", \"function\": {\"name\": \"tool\", \"description\": \"Returns the sum of two numbers.\", \"parameters\": {\"type\": \"object\", \"properties\": {\"a\": {\"type\": \"integer\", \"description\": \"aaa\"}, \"b\": {\"type\": \"integer\", \"description\": \"bbb\"}}, \"required\": [\"a\", \"b\"]}, \"return\": {\"type\": \"array\", \"prefixItems\": [{\"type\": \"integer\"}, {\"type\": \"integer\"}], \"description\": \"c: ccc\\n    d: ddd\"}}}\n",
      "</tools>\n",
      "\n",
      "For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n",
      "<tool_call>\n",
      "{\"name\": <function-name>, \"arguments\": <args-json-object>}\n",
      "</tool_call><|im_end|>\n",
      "<|im_start|>user\n",
      "hello<|im_end|>\n",
      "\n"
     ]
    }
   ],
   "source": [
    "async def tool(a: int, b: int) -> tuple[int, int]:\n",
    "    \"\"\"\n",
    "    Returns the sum of two numbers.\n",
    "\n",
    "    Args:\n",
    "        a: aaa\n",
    "        b: bbb\n",
    "        \n",
    "\n",
    "    Returns:\n",
    "        c: ccc\n",
    "        d: ddd\n",
    "    \"\"\"\n",
    "    return a + b, a-b\n",
    "a = tokenizer.apply_chat_template(\n",
    "    [\n",
    "        {\"role\": \"user\", \"content\": \"hello\"},\n",
    "    ],\n",
    "    tools = [tool],\n",
    "    tokenize=False\n",
    ")\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<|im_start|>system\n",
      "666\n",
      "\n",
      "# Tools\n",
      "\n",
      "You may call one or more functions to assist with the user query.\n",
      "\n",
      "You are provided with function signatures within <tools></tools> XML tags:\n",
      "<tools>\n",
      "{\"type\": \"function\", \"function\": {\"name\": \"tool\", \"description\": \"Returns the sum of two numbers.\", \"parameters\": {\"type\": \"object\", \"properties\": {\"a\": {\"type\": \"integer\", \"description\": \"aaa\"}, \"b\": {\"type\": \"integer\", \"description\": \"bbb\"}}, \"required\": [\"a\", \"b\"]}, \"return\": {\"type\": \"array\", \"prefixItems\": [{\"type\": \"integer\"}, {\"type\": \"integer\"}], \"description\": \"c: ccc\\n    d: ddd\"}}}\n",
      "</tools>\n",
      "\n",
      "For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n",
      "<tool_call>\n",
      "{\"name\": <function-name>, \"arguments\": <args-json-object>}\n",
      "</tool_call><|im_end|>\n",
      "<|im_start|>user\n",
      "hello<|im_end|>\n",
      "\n"
     ]
    }
   ],
   "source": [
    "async def tool(a: int, b: int) -> tuple[int, int]:\n",
    "    \"\"\"\n",
    "    Returns the sum of two numbers.\n",
    "\n",
    "    Args:\n",
    "        a: aaa\n",
    "        b: bbb\n",
    "        \n",
    "\n",
    "    Returns:\n",
    "        c: ccc\n",
    "        d: ddd\n",
    "    \"\"\"\n",
    "    return a + b, a-b\n",
    "a = tokenizer.apply_chat_template(\n",
    "    [\n",
    "        {\"role\": \"system\", \"content\": \"666\"},\n",
    "        {\"role\": \"user\", \"content\": \"hello\"},\n",
    "    ],\n",
    "    tools = [tool],\n",
    "    tokenize=False\n",
    ")\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'id': 'chatcmpl-0c0b57a4032246519e6c0f134a71938f',\n",
       " 'object': 'chat.completion',\n",
       " 'created': 1748121718,\n",
       " 'model': 'Qwen2.5-Coder-7B-Instruct',\n",
       " 'choices': [{'index': 0,\n",
       "   'message': {'role': 'assistant',\n",
       "    'reasoning_content': None,\n",
       "    'content': 'To create an XML request that calls a function (e.g., `add`) with arguments to perform the calculation `3 + 3`, you can structure your XML as follows:\\n\\n```xml\\n<request>\\n    <function name=\"add\">\\n        <arg key=\"a\">3</arg>\\n        <arg key=\"b\">3</arg>\\n    </function>\\n</request>\\n```\\n\\nHere\\'s a breakdown of what this XML does:\\n- `<request>`: The root element of the request.\\n- `<function name=\"add\">`: Specifies the function to be called, in this case, `add`.\\n- `<arg key=\"a\">3</arg>`: An argument passed to the `add` function, where `key` is `a` and the value is `3`.\\n- `<arg key=\"b\">3</arg>`: Another argument passed to the `add` function, where `key` is `b` and the value is `3`.\\n\\nThis XML structure assumes that the system or service consuming this XML understands how to interpret the `function` and `arg` elements to execute the specified operation.',\n",
       "    'tool_calls': []},\n",
       "   'logprobs': None,\n",
       "   'finish_reason': 'stop',\n",
       "   'stop_reason': None}],\n",
       " 'usage': {'prompt_tokens': 76,\n",
       "  'total_tokens': 306,\n",
       "  'completion_tokens': 230,\n",
       "  'prompt_tokens_details': None},\n",
       " 'prompt_logprobs': None}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import requests\n",
    "chat_completion = requests.post(\n",
    "    url = \"http://localhost:8000/v1/chat/completions\",\n",
    "    json=dict(\n",
    "        model=\"Qwen2.5-Coder-7B-Instruct\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"wrtie xml code: <request></request> to call function, e.g. <tool_call>{'name': 'add', 'args': {'a': 1, 'b': 2}}, calculate 3+3.\",\n",
    "        },\n",
    "    ],\n",
    "    temperature=1,\n",
    "    )\n",
    ")\n",
    "data = chat_completion.json()\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'id': 'chatcmpl-20c2f62eed1348489bdcd0f7f0dca686',\n",
       " 'object': 'chat.completion',\n",
       " 'created': 1748121979,\n",
       " 'model': 'Qwen2.5-7B-Instruct',\n",
       " 'choices': [{'index': 0,\n",
       "   'message': {'role': 'assistant',\n",
       "    'reasoning_content': None,\n",
       "    'content': 'To create an XML request that calls a function and includes arguments, you can structure the XML as follows. In this case, we\\'ll simulate a request to perform an addition operation with the numbers 3 and 3.\\n\\nHere\\'s how you can write the XML code:\\n\\n```xml\\n<request>\\n    <function name=\"add\">\\n        <arg name=\"a\">3</arg>\\n        <arg name=\"b\">3</arg>\\n    </function>\\n',\n",
       "    'tool_calls': []},\n",
       "   'logprobs': None,\n",
       "   'finish_reason': 'stop',\n",
       "   'stop_reason': '</request>'}],\n",
       " 'usage': {'prompt_tokens': 76,\n",
       "  'total_tokens': 172,\n",
       "  'completion_tokens': 96,\n",
       "  'prompt_tokens_details': None},\n",
       " 'prompt_logprobs': None}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import requests\n",
    "chat_completion = requests.post(\n",
    "    url = \"http://localhost:8000/v1/chat/completions\",\n",
    "    json=dict(\n",
    "        model=\"Qwen2.5-7B-Instruct\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"wrtie xml code: <request></request> to call function, e.g. <tool_call>{'name': 'add', 'args': {'a': 1, 'b': 2}}, calculate 3+3.\",\n",
    "        },\n",
    "    ],\n",
    "    temperature=1,\n",
    "    stop=[\"</request>\"],\n",
    "    )\n",
    ")\n",
    "data = chat_completion.json()\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'</request>'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openai.types.chat.chat_completion import ChatCompletion\n",
    "comp = ChatCompletion(**data)\n",
    "comp.choices[0].stop_reason"
   ]
  }
 ],
 "metadata": {
  "fileId": "f928e676-1eec-460a-818a-045b53cd6f21",
  "filePath": "/opt/tiger/verl/recurrent/test/test_tool_tokenize.ipynb",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
